import { SetMetadata, applyDecorators } from '@nestjs/common'
import { ApiBearerAuth, ApiUnauthorizedResponse, ApiForbiddenResponse } from '@nestjs/swagger'

/**
 * 角色枚举
 */
export enum UserRole {
  SUPER_ADMIN = 'super_admin',
  ADMIN = 'admin',
  EDITOR = 'editor',
  AUTHOR = 'author',
  CONTRIBUTOR = 'contributor',
  SUBSCRIBER = 'subscriber',
  GUEST = 'guest'
}

/**
 * 权限枚举
 */
export enum Permission {
  // 用户管理权限
  USER_CREATE = 'user:create',
  USER_READ = 'user:read',
  USER_UPDATE = 'user:update',
  USER_DELETE = 'user:delete',
  USER_MANAGE = 'user:manage',

  // 文章管理权限
  ARTICLE_CREATE = 'article:create',
  ARTICLE_READ = 'article:read',
  ARTICLE_UPDATE = 'article:update',
  ARTICLE_DELETE = 'article:delete',
  ARTICLE_PUBLISH = 'article:publish',
  ARTICLE_MANAGE = 'article:manage',

  // 分类管理权限
  CATEGORY_CREATE = 'category:create',
  CATEGORY_READ = 'category:read',
  CATEGORY_UPDATE = 'category:update',
  CATEGORY_DELETE = 'category:delete',
  CATEGORY_MANAGE = 'category:manage',

  // 标签管理权限
  TAG_CREATE = 'tag:create',
  TAG_READ = 'tag:read',
  TAG_UPDATE = 'tag:update',
  TAG_DELETE = 'tag:delete',
  TAG_MANAGE = 'tag:manage',

  // 评论管理权限
  COMMENT_CREATE = 'comment:create',
  COMMENT_READ = 'comment:read',
  COMMENT_UPDATE = 'comment:update',
  COMMENT_DELETE = 'comment:delete',
  COMMENT_MODERATE = 'comment:moderate',
  COMMENT_MANAGE = 'comment:manage',

  // 文件管理权限
  FILE_UPLOAD = 'file:upload',
  FILE_READ = 'file:read',
  FILE_UPDATE = 'file:update',
  FILE_DELETE = 'file:delete',
  FILE_MANAGE = 'file:manage',

  // 系统设置权限
  SETTING_READ = 'setting:read',
  SETTING_UPDATE = 'setting:update',
  SETTING_MANAGE = 'setting:manage',

  // 系统管理权限
  SYSTEM_MONITOR = 'system:monitor',
  SYSTEM_LOG = 'system:log',
  SYSTEM_BACKUP = 'system:backup',
  SYSTEM_MANAGE = 'system:manage'
}

/**
 * 角色权限映射
 */
export const ROLE_PERMISSIONS: Record<UserRole, Permission[]> = {
  [UserRole.SUPER_ADMIN]: Object.values(Permission),
  [UserRole.ADMIN]: [
    // 用户管理（除了超级管理员操作）
    Permission.USER_CREATE,
    Permission.USER_READ,
    Permission.USER_UPDATE,
    Permission.USER_DELETE,

    // 内容管理
    Permission.ARTICLE_CREATE,
    Permission.ARTICLE_READ,
    Permission.ARTICLE_UPDATE,
    Permission.ARTICLE_DELETE,
    Permission.ARTICLE_PUBLISH,
    Permission.ARTICLE_MANAGE,

    Permission.CATEGORY_CREATE,
    Permission.CATEGORY_READ,
    Permission.CATEGORY_UPDATE,
    Permission.CATEGORY_DELETE,
    Permission.CATEGORY_MANAGE,

    Permission.TAG_CREATE,
    Permission.TAG_READ,
    Permission.TAG_UPDATE,
    Permission.TAG_DELETE,
    Permission.TAG_MANAGE,

    Permission.COMMENT_CREATE,
    Permission.COMMENT_READ,
    Permission.COMMENT_UPDATE,
    Permission.COMMENT_DELETE,
    Permission.COMMENT_MODERATE,
    Permission.COMMENT_MANAGE,

    // 文件管理
    Permission.FILE_UPLOAD,
    Permission.FILE_READ,
    Permission.FILE_UPDATE,
    Permission.FILE_DELETE,
    Permission.FILE_MANAGE,

    // 系统设置
    Permission.SETTING_READ,
    Permission.SETTING_UPDATE,
    Permission.SETTING_MANAGE,

    // 系统监控
    Permission.SYSTEM_MONITOR,
    Permission.SYSTEM_LOG
  ],
  [UserRole.EDITOR]: [
    // 内容管理
    Permission.ARTICLE_CREATE,
    Permission.ARTICLE_READ,
    Permission.ARTICLE_UPDATE,
    Permission.ARTICLE_DELETE,
    Permission.ARTICLE_PUBLISH,

    Permission.CATEGORY_CREATE,
    Permission.CATEGORY_READ,
    Permission.CATEGORY_UPDATE,
    Permission.CATEGORY_DELETE,

    Permission.TAG_CREATE,
    Permission.TAG_READ,
    Permission.TAG_UPDATE,
    Permission.TAG_DELETE,

    Permission.COMMENT_READ,
    Permission.COMMENT_UPDATE,
    Permission.COMMENT_DELETE,
    Permission.COMMENT_MODERATE,

    // 文件管理
    Permission.FILE_UPLOAD,
    Permission.FILE_READ,
    Permission.FILE_UPDATE,
    Permission.FILE_DELETE,

    // 基础设置查看
    Permission.SETTING_READ
  ],
  [UserRole.AUTHOR]: [
    // 内容创作
    Permission.ARTICLE_CREATE,
    Permission.ARTICLE_READ,
    Permission.ARTICLE_UPDATE, // 只能编辑自己的文章

    Permission.CATEGORY_READ,

    Permission.TAG_CREATE,
    Permission.TAG_READ,

    Permission.COMMENT_READ,
    Permission.COMMENT_CREATE,

    // 文件上传
    Permission.FILE_UPLOAD,
    Permission.FILE_READ
  ],
  [UserRole.CONTRIBUTOR]: [
    // 内容贡献
    Permission.ARTICLE_CREATE,
    Permission.ARTICLE_READ,
    Permission.CATEGORY_READ,
    Permission.TAG_CREATE,
    Permission.TAG_READ,
    Permission.COMMENT_CREATE,
    Permission.COMMENT_READ,
    Permission.FILE_UPLOAD,
    Permission.FILE_READ
  ],
  [UserRole.SUBSCRIBER]: [
    // 基础阅读和评论
    Permission.ARTICLE_READ,
    Permission.CATEGORY_READ,
    Permission.TAG_READ,
    Permission.COMMENT_CREATE,
    Permission.COMMENT_READ,
    Permission.FILE_READ
  ],
  [UserRole.GUEST]: [
    // 仅阅读权限
    Permission.ARTICLE_READ,
    Permission.CATEGORY_READ,
    Permission.TAG_READ,
    Permission.COMMENT_READ,
    Permission.FILE_READ
  ]
}

// 元数据键
export const ROLES_KEY = 'roles'
export const PERMISSIONS_KEY = 'permissions'
export const IS_PUBLIC_KEY = 'isPublic'
export const RESOURCE_KEY = 'resource'
export const ACTION_KEY = 'action'
export const OWNER_ONLY_KEY = 'ownerOnly'

/**
 * 角色装饰器
 * 用于指定接口需要的角色
 *
 * @param roles 允许访问的角色列表
 *
 * @example
 * ```typescript
 * @Get('admin')
 * @Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN)
 * adminOnly() {
 *   return 'Admin only content';
 * }
 * ```
 */
export const Roles = (...roles: UserRole[]) => SetMetadata(ROLES_KEY, roles)

/**
 * 权限装饰器
 * 用于指定接口需要的权限
 *
 * @param permissions 需要的权限列表
 *
 * @example
 * ```typescript
 * @Post()
 * @Permissions(Permission.ARTICLE_CREATE)
 * createArticle(@Body() dto: CreateArticleDto) {
 *   return this.articleService.create(dto);
 * }
 * ```
 */
export const Permissions = (...permissions: Permission[]) => SetMetadata(PERMISSIONS_KEY, permissions)

/**
 * 公开接口装饰器
 * 用于标记不需要认证的公开接口
 *
 * @example
 * ```typescript
 * @Get('public')
 * @Public()
 * getPublicData() {
 *   return this.service.getPublicData();
 * }
 * ```
 */
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true)

/**
 * 资源装饰器
 * 用于标记资源类型，配合权限检查
 *
 * @param resource 资源名称
 *
 * @example
 * ```typescript
 * @Controller('articles')
 * @Resource('article')
 * export class ArticleController {}
 * ```
 */
export const Resource = (resource: string) => SetMetadata(RESOURCE_KEY, resource)

/**
 * 操作装饰器
 * 用于标记操作类型，配合权限检查
 *
 * @param action 操作名称
 *
 * @example
 * ```typescript
 * @Post()
 * @Action('create')
 * create(@Body() dto: CreateDto) {}
 * ```
 */
export const Action = (action: string) => SetMetadata(ACTION_KEY, action)

/**
 * 仅所有者装饰器
 * 用于标记只有资源所有者才能访问的接口
 *
 * @example
 * ```typescript
 * @Put(':id')
 * @OwnerOnly()
 * updateMyArticle(@Param('id') id: string, @Body() dto: UpdateArticleDto) {
 *   return this.articleService.updateByOwner(id, dto, req.user.id);
 * }
 * ```
 */
export const OwnerOnly = () => SetMetadata(OWNER_ONLY_KEY, true)

/**
 * 认证装饰器组合
 * 提供常用的认证配置组合
 */
export class Auth {
  /**
   * 需要登录
   */
  static Required() {
    return applyDecorators(ApiBearerAuth(), ApiUnauthorizedResponse({ description: '未授权访问' }))
  }

  /**
   * 管理员权限
   */
  static Admin() {
    return applyDecorators(
      Roles(UserRole.ADMIN, UserRole.SUPER_ADMIN),
      ApiBearerAuth(),
      ApiUnauthorizedResponse({ description: '未授权访问' }),
      ApiForbiddenResponse({ description: '权限不足' })
    )
  }

  /**
   * 超级管理员权限
   */
  static SuperAdmin() {
    return applyDecorators(
      Roles(UserRole.SUPER_ADMIN),
      ApiBearerAuth(),
      ApiUnauthorizedResponse({ description: '未授权访问' }),
      ApiForbiddenResponse({ description: '权限不足' })
    )
  }

  /**
   * 编辑权限
   */
  static Editor() {
    return applyDecorators(
      Roles(UserRole.EDITOR, UserRole.ADMIN, UserRole.SUPER_ADMIN),
      ApiBearerAuth(),
      ApiUnauthorizedResponse({ description: '未授权访问' }),
      ApiForbiddenResponse({ description: '权限不足' })
    )
  }

  /**
   * 作者权限
   */
  static Author() {
    return applyDecorators(
      Roles(UserRole.AUTHOR, UserRole.EDITOR, UserRole.ADMIN, UserRole.SUPER_ADMIN),
      ApiBearerAuth(),
      ApiUnauthorizedResponse({ description: '未授权访问' }),
      ApiForbiddenResponse({ description: '权限不足' })
    )
  }

  /**
   * 用户权限（已登录用户）
   */
  static User() {
    return applyDecorators(
      Roles(...Object.values(UserRole)),
      ApiBearerAuth(),
      ApiUnauthorizedResponse({ description: '未授权访问' }),
      ApiForbiddenResponse({ description: '权限不足' })
    )
  }

  /**
   * 公开访问
   */
  static Public() {
    return Public()
  }

  /**
   * 资源所有者权限
   * @param fallbackRoles 备用角色（如果不是所有者，需要的角色）
   */
  static Owner(...fallbackRoles: UserRole[]) {
    return applyDecorators(
      OwnerOnly(),
      ...(fallbackRoles.length > 0 ? [Roles(...fallbackRoles)] : []),
      ApiBearerAuth(),
      ApiUnauthorizedResponse({ description: '未授权访问' }),
      ApiForbiddenResponse({ description: '权限不足或非资源所有者' })
    )
  }

  /**
   * 自定义权限
   * @param permissions 需要的权限
   */
  static Permission(...permissions: Permission[]) {
    return applyDecorators(
      Permissions(...permissions),
      ApiBearerAuth(),
      ApiUnauthorizedResponse({ description: '未授权访问' }),
      ApiForbiddenResponse({ description: '权限不足' })
    )
  }

  /**
   * 资源权限组合
   * @param resource 资源名称
   * @param action 操作名称
   * @param permissions 需要的权限
   */
  static ResourceAction(resource: string, action: string, ...permissions: Permission[]) {
    return applyDecorators(
      Resource(resource),
      Action(action),
      Permissions(...permissions),
      ApiBearerAuth(),
      ApiUnauthorizedResponse({ description: '未授权访问' }),
      ApiForbiddenResponse({ description: '权限不足' })
    )
  }
}

/**
 * 内容管理权限装饰器
 */
export class ContentAuth {
  /**
   * 文章创建权限
   */
  static ArticleCreate() {
    return Auth.Permission(Permission.ARTICLE_CREATE)
  }

  /**
   * 文章编辑权限
   */
  static ArticleEdit() {
    return Auth.Permission(Permission.ARTICLE_UPDATE)
  }

  /**
   * 文章删除权限
   */
  static ArticleDelete() {
    return Auth.Permission(Permission.ARTICLE_DELETE)
  }

  /**
   * 文章发布权限
   */
  static ArticlePublish() {
    return Auth.Permission(Permission.ARTICLE_PUBLISH)
  }

  /**
   * 文章管理权限
   */
  static ArticleManage() {
    return Auth.Permission(Permission.ARTICLE_MANAGE)
  }

  /**
   * 文章更新权限（别名）
   */
  static ArticleUpdate() {
    return Auth.Permission(Permission.ARTICLE_UPDATE)
  }

  /**
   * 文章查看权限
   */
  static ArticleView() {
    return Auth.Permission(Permission.ARTICLE_READ)
  }

  /**
   * 分类创建权限
   */
  static CategoryCreate() {
    return Auth.Permission(Permission.CATEGORY_CREATE)
  }

  /**
   * 分类编辑权限
   */
  static CategoryEdit() {
    return Auth.Permission(Permission.CATEGORY_UPDATE)
  }

  /**
   * 分类删除权限
   */
  static CategoryDelete() {
    return Auth.Permission(Permission.CATEGORY_DELETE)
  }

  /**
   * 分类管理权限
   */
  static CategoryManage() {
    return Auth.Permission(Permission.CATEGORY_MANAGE)
  }

  /**
   * 标签管理权限
   */
  static TagManage() {
    return Auth.Permission(Permission.TAG_MANAGE)
  }

  /**
   * 评论管理权限
   */
  static CommentManage() {
    return Auth.Permission(Permission.COMMENT_MANAGE)
  }

  /**
   * 评论审核权限
   */
  static CommentModerate() {
    return Auth.Permission(Permission.COMMENT_MODERATE)
  }
}

/**
 * 系统管理权限装饰器
 */
export class SystemAuth {
  /**
   * 用户管理权限
   */
  static UserManage() {
    return Auth.Permission(Permission.USER_MANAGE)
  }

  /**
   * 文件管理权限
   */
  static FileManage() {
    return Auth.Permission(Permission.FILE_MANAGE)
  }

  /**
   * 系统设置权限
   */
  static SettingManage() {
    return Auth.Permission(Permission.SETTING_MANAGE)
  }

  /**
   * 系统监控权限
   */
  static SystemMonitor() {
    return Auth.Permission(Permission.SYSTEM_MONITOR)
  }

  /**
   * 系统管理权限
   */
  static SystemManage() {
    return Auth.Permission(Permission.SYSTEM_MANAGE)
  }
}

/**
 * 检查用户是否有指定权限
 * @param userRole 用户角色
 * @param permission 需要检查的权限
 * @returns 是否有权限
 */
export function hasPermission(userRole: UserRole, permission: Permission): boolean {
  const rolePermissions = ROLE_PERMISSIONS[userRole] || []
  return rolePermissions.includes(permission)
}

/**
 * 检查用户是否有指定角色
 * @param userRole 用户角色
 * @param requiredRoles 需要的角色列表
 * @returns 是否有角色
 */
export function hasRole(userRole: UserRole, requiredRoles: UserRole[]): boolean {
  return requiredRoles.includes(userRole)
}

/**
 * 获取角色的所有权限
 * @param role 角色
 * @returns 权限列表
 */
export function getRolePermissions(role: UserRole): Permission[] {
  return ROLE_PERMISSIONS[role] || []
}

/**
 * 获取权限所需的最低角色
 * @param permission 权限
 * @returns 角色列表
 */
export function getPermissionRoles(permission: Permission): UserRole[] {
  const roles: UserRole[] = []

  for (const [role, permissions] of Object.entries(ROLE_PERMISSIONS)) {
    if (permissions.includes(permission)) {
      roles.push(role as UserRole)
    }
  }

  return roles
}
